<?php
// +----------------------------------------------------------------------
// | QSCMS
// +----------------------------------------------------------------------
// | Copyright (c)  2025 https://www.qqss.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed QSCMS is not free software, commercial use must purchase official license from official website to avoid unnecessary legal disputes.
// +----------------------------------------------------------------------
// | Author: Contract 990504246@qq.com
// +----------------------------------------------------------------------

namespace app\adminapi\controller;

use app\common\model\AdminUser;
use app\common\util\TokenAuth;
use app\service\common\Api;
use app\common\exception\HttpResponseException;

class Base extends Api
{
    // User information
    protected $user;
    // Number of items per page
    protected $limit;
    // Methods that do not require login
    protected $noLoginAction = [];
    // Methods that need to record permissions
    protected $permissions = [];
    // Methods that need to record operation logs
    protected $logs = [];

    // Request parameters
    protected $request;

    public function __construct()
    {
        parent::__construct();
        $this->request = request();
        $this->checkLogin();
        $this->setList();
    }

    /**
     * Check login
     */
    protected function checkLogin()
    {
        // If it is a method that does not require login, it will be passed directly
        if (in_array(request()->action, $this->noLoginAction)) {
            return true;
        }
        // Check token
        try {
            $user = TokenAuth::parseToken('admin');
        } catch (\Exception $e) {
            throw new HttpResponseException(401, ['msg' => $e->getMessage()]);
        }
        // Start checking user permissions
        $this->user = AdminUser::find($user['id']);
        // Set request's user, used for logging
        request()->user = $this->user;

        // Automatically register session, used for plugin interface communication
        $this->registerAdminSession();

        // Check node permissions
        $this->checkAuth();
    }

    /**
     * Check permissions
     */
    protected function checkAuth()
    {
        // If $this->user->roles contains id=1, it is a super administrator, and it will be passed directly
        if ($this->user->roles->where('role_id', 1)->count()) {
            return true;
        }
        $action     = request()->action;
        $controller = request()->controller;
        $reflection = new \ReflectionMethod($controller, $action);
        $docComment = $reflection->getDocComment();
        // If the comment @auth true is added, it will be added to the permission verification
        if (strpos($docComment, '@auth true')) {
            if (in_array($action, $this->permissions)) {
                $path = request()->path();
                $auth = new \app\common\util\RoleAuth();
                if (!$auth->check($path, $this->user)) {
                    throw new HttpResponseException(403, ['msg' => trans('no_permission')]);
                }
            }
        }
    }

    /**
     * Register admin session, used for plugin interface communication
     */
    protected function registerAdminSession()
    {
        // Use webman's session
        $session = request()->session();

        // Get role ID list
        $role_ids = [];
        foreach ($this->user->roles as $role) {
            $role_ids[] = $role->role_id;
        }

        // Store admin information in session
        $session->set('admin_user', [
            'id'             => $this->user->id,
            'username'       => $this->user->username,
            'nickname'       => $this->user->nickname,
            'email'          => $this->user->email,
            'avatar'         => $this->user->avatar,
            'roles'          => $role_ids,
            'is_super_admin' => $this->user->roles->where('role_id', 1)->count() > 0,
            'login_time'     => time(),
            'session_id'     => $session->getId()
        ]);

        // Set session expiration time (2 hours)
        $session->set('admin_session_expire', time() + 7200);
    }

    /**
     * Set list pagination
     */
    protected function setList()
    {
        $this->limit = $this->request->post('limit', 20);
    }

}
